package com.qilin.hscs.hm.mqtt.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.qilin.hscs.hm.convert.DTO2DOConvert;
import com.qilin.hscs.hm.dao.DeviceRepository;
import com.qilin.hscs.hm.dao.RoomRepository;
import com.qilin.hscs.hm.dto.DeviceDto;
import com.qilin.hscs.hm.dto.RoomDto;
import com.qilin.hscs.hm.dto.SingleBaseDeviceEPDto;
import com.qilin.hscs.hm.enums.CommonException;
import com.qilin.hscs.hm.enums.ResultEnum;
import com.qilin.hscs.hm.mqtt.service.RoomService;
import com.qilin.hscs.hm.mqtt.service.common.ServiceCommon;
import com.qilin.hscs.hm.pojo.Device;
import com.qilin.hscs.hm.pojo.Room;
import com.qilin.hscs.hm.util.MqttResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service("room")
public class RoomServiceImpl extends ServiceCommon implements RoomService {

    @Autowired
    private RoomRepository roomRepository;

    @Autowired
    private DeviceRepository deviceRepository;

    private JSONObject msgObject;

    private long start = System.currentTimeMillis();
    private static final Logger logger= LogManager.getLogger(DeviceServiceImpl.class.getName());

    /**
     * 找出所有房间，按楼层排列
     */
    @Override
    public void findTotalRooms() {
        log.info("查询所有设备");
        String phone  = dataObj.getString("phone");
        List <Room> floorList = this.roomRepository.findDistinctRooms();
        List<Room> rooms = this.roomRepository.findAll();
        Map<String, Object> data = new HashMap<>();
        data.put("phone",phone);
        ArrayList<Map<String, Object>> mapRoomList =new ArrayList<>();
        for (int i = 0; i <floorList.size() ; i++) {
            Map<String, Object> mapFloor = new HashMap<>();
            String floor = floorList.get(i).getFloor();
            mapFloor.put("floor",floor);
            ArrayList<Room> roomArrayList = new ArrayList<>();
            for (Room room :rooms ) {
                if(room.getFloor().equals(floorList.get(i).getFloor())) {
                    roomArrayList.add(room);
                }
            }
            mapFloor.put("rooms",roomArrayList);
            mapRoomList.add(mapFloor);
        }
        data.put("floors",mapRoomList);
        msg= MqttResultUtil.getResult(7001, 0, data);
    }

    /**
     * 添加房间
     */
    @Override
    public void addRoom() {
        log.info("添加房间");
        try {
            JSONObject roomObj = msgObj.getJSONObject("data");
            RoomDto roomDto = roomObj.toJavaObject(RoomDto.class);
            Room room = DTO2DOConvert.RoomDto2Room(roomDto);
            room.setIcon(roomDto.getIcon());
            room.setName(roomDto.getName());
            room.setFloor(room.getFloor());
            this.roomRepository.save(room);
            Map<String, Object> data = new HashMap<>();
            data.put("id",room.getId());
            data.put("name",room.getName());
            data.put("icon",room.getIcon());
            data.put("floor",room.getFloor());
            msg= MqttResultUtil.getResult(7002, 0, data);
        } catch (Exception e) {
            log.error("保存房间信息方法内部错误",e);
        } finally {
            log.info("保存用户信息结束,用时" + (System.currentTimeMillis() - start) + "毫秒");
        }

    }

    /**
     * 修改房间
     */
    @Override
    public void alterRoom() {
        log.info("修改房间");
          JSONObject roomObj = msgObj.getJSONObject("data");
          RoomDto roomDto = roomObj.toJavaObject(RoomDto.class);
          Room room = DTO2DOConvert.RoomDto2Room(roomDto);
          Room result = roomRepository.findOne(roomDto.getId());
          if (result != null){
              room.setIcon(roomDto.getIcon());
              room.setName(roomDto.getName());
              room.setFloor(room.getFloor());
              this.roomRepository.save(room);
              Map<String, Object> data = new HashMap<>();
              data.put("id",room.getId());
              data.put("name",room.getName());
              data.put("icon",room.getIcon());
              data.put("floor",room.getFloor());
              msg= MqttResultUtil.getResult(7003, 0, data);
          }else {
              log.error("【修改房间】修改状态不正确, rId={}", room.getId());
              throw new CommonException(ResultEnum.ROOM_NOT_EXIST);
          }
    }

    /**
     * 删除房间
     */
    @Override
    public void delRoom() {
        log.info("删除房间");
        JSONObject roomObj = msgObj.getJSONObject("data");
        Integer id = roomObj.getInteger("rId");
        Room result = roomRepository.findOne(id);
        if (result.getId() != null && result.getId() != 1){
            List<Device> deviceList = deviceRepository.findByRoomId(result.getId());
            for (int i = 0; i <deviceList.size() ; i++){
                int deviceId = deviceList.get(i).getId();
                Device device = deviceRepository.findOne(deviceId);
                if (device.getId() != null){
                    device.setRoomId(1);
                    this.deviceRepository.save(device);
                }
            }
            this.roomRepository.delete(result);
            Map<String, Object> data = new HashMap<>();
            data.put("rId",result.getId());
            msg= MqttResultUtil.getResult(7004, 0, data);
        }else {
            log.error("【删除房间】删除状态不正确, rId={}", result.getId());
            throw new CommonException(ResultEnum.ROOM_NOT_EXIST);
        }
    }


    /**
     * 根据房间取得设备
     */
    private final SingleBaseDeviceEPDto readDataToSingleBaseDeviceDto() {
        JSONObject dataObj = msgObject.getJSONObject("data");
        SingleBaseDeviceEPDto baseDeviceEPDto = dataObj.toJavaObject(SingleBaseDeviceEPDto.class);
        logger.debug(baseDeviceEPDto);
        return baseDeviceEPDto;
    }

    @Override
    public void handle() {
        switch (cmd) {
            case 6001:
                findTotalRooms();
                isflushToGateway(false);
                flush();
                break;
            case 6002:
                addRoom();
                isflushToGateway(false);
                flush();
                break;
            case 6003:
                alterRoom();
                isflushToGateway(false);
                flush();
                break;
            case 6004:
                delRoom();
                isflushToGateway(false);
                flush();
                break;
        }

    }

    @Override
    public void initailData(){
        try {
            msgObj = JSON.parseObject(msg);
            dataObj = msgObj.getJSONObject("data");
        } catch (JSONException je) {
            logger.warn("传输过来的json字符串有误，主机无法解析 错误详细情况为={}", je.getStackTrace());
        }
        cmd = msgObj.getInteger("cmd");
        if (topicVar != null) {
            if (!topicVar.contains("/rsp")) {
                phone = msgObj.getString("phone");
            }
        }
    }
}
